#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <map>
using std::cout;
using std::endl;
using std::string;
using std::istringstream;
using std::map;
using std::ifstream;
using std::ofstream;
//流程思路分析：
//思路是同之前的做法，只不过处理的时候略微做一些改动
//之前是使用vector来进行存储，存储的是一个一个record对象
//record对象里面时string和int的映射
//现在使用map来存储，map里面的元素其实是pair类型
//pair我们可以使用string和int来组合
//所以之前的record其实现在就变成了map里面的pair
//....
class Dictionary{
public:
    //读取输入文件，截取每个单词
    //针对每出现的一个单词需要进行词频的统计
    //如何统计呢？
    //第一次出现肯定是直接设置1，后续出现+1操作
    //对应的代码：第一次出现需要创建record对象，后续
    //再次出现那么只需要将record对象里面的词频+1操作即可
    //解析单词的过程中有两种处理方式
    //1.先读取一行，然后对一行字符进行解析(istringstream)
    //2.ifs >> word每次读取一个单词
    //判断这个单词里面有没有数字或者其他的非法字符
    //如果有则返回false；如果没有则返回true
    bool is_word(const string & word){
        //获取的是首元素的迭代器，可以理解为是指向
        //首元素的指针
        auto it = word.begin();
        //不断地移动指针，不断判断每一位是否是数字
        //如果是数字，则直接返回false
        //如果全部遍历一遍，都没有返回false，则最终返回true
        while(it != word.end()){
            if(!isalpha(*it)){
                return false;
            }
            ++it;
        }
        return true;
    }
    void read(const string & filename){
        ifstream ifs(filename);
        string line;
        while(getline(ifs, line)){
            istringstream iss(line);
            string word;
            while(iss >> word){
                //判断是否是字母单词
                //word里面只有大小写字母
                if(is_word(word)){
                    //判断word是否是第一次出现？？
                    ++_dict[word];
                }
            }
        }
    }
    //将词频信息输出到文件中显示出来即可
    void store(const string & filename){
        ofstream ofs(filename);
        //使用迭代器再来实现一遍
        auto it = _dict.begin();
        while(it != _dict.end()){
            //以下两种方式均可以
            //此时迭代器对象是不是就像透明膜一样
            ofs << it->first << " " << it->second << endl;
            //ofs << (*it)._word << " " << (*it)._frequency << endl;

            ++it;
        }
    
        ofs.close();
    }

private:
    //vector<Record> _dict;
    map<string,int> _dict;
};


void test(){
    //面向对象和面向过程的编程语言之间书写的区别
    Dictionary dict;
    dict.read("The_Holy_Bible.txt");
    dict.store("bible.data");
}

int main()
{
    test();
    return 0;
}

